<template>
  <a-layout>
    <a-layout-sider>
      <ul class="design-combos">
        <li class="design-combo" v-for="(field,type) of defaultConfig" :draggable="true"
            @dragstart="dragstart($event, {fieldType: type, type: 'add'})">
          <div class="title">
            {{ field.label }}
          </div>
        </li>
      </ul>
    </a-layout-sider>
    <a-layout-content>
      <div class="design-content">
        <div class="design-header">
          <a-button type="link" @click="save">
            保存
          </a-button>
          <a-button type="link" @click="visible = true">
            预览
          </a-button>
          <a-button type="link" @click="clear">
            清空
          </a-button>
          <a-button type="link" @click="setDefaultValue">
            设置默认值
          </a-button>
        </div>
        <div class="design-body" @dragover.prevent @drop="drop">
          <a-form ref="form" :model="form.model" :rules="form.rules" :label-col="form.settings.labelCol"
                  :wrapper-col="form.settings.wrapperCol" :labelAlign="form.settings.labelAlign"
                  :layout="form.settings.layout">
            <div class="design-item" v-for="(field, index) in form.fields" :ref="field.name" :key="field.name"
                 :draggable="true" @dragover.prevent @drop="drop($event, index)" @click="click(field)"
                 @dragstart="dragstart($event, {index: index, type: 'sort'})">
              <DeleteOutlined class="delete" @click="remove($event,index)"/>
              <field-render v-if="field.name" :field="field" v-model:value="form.model[field.name]"
                            :options="options[field && field.datasource ? field.datasource : field.name]"/>
            </div>
          </a-form>
        </div>
      </div>
    </a-layout-content>
    <a-layout-sider class="design-setting">
      <a-tabs v-model:activeKey="activeKey">
        <a-tab-pane key="formSetting" tab="表单配置">
          <form-setting :settings="form.settings"/>
        </a-tab-pane>
        <a-tab-pane key="fieldSetting" tab="表单项配置">
          <field-setting :field="field"/>
        </a-tab-pane>
      </a-tabs>
    </a-layout-sider>
  </a-layout>
  <a-modal v-if="visible" title="表单预览" v-model:visible="visible" width="800px" @ok="ok">
    <from-render ref="render" :form="form" :model="form.model" :options="options"/>
    <template #footer>
      <a-button key="submit" type="primary" @click="ok">
        验证
      </a-button>
      <a-button key="back" @click="reset">
        重置
      </a-button>
    </template>
  </a-modal>
</template>

<script>
import {DragOutlined, DeleteOutlined} from '@ant-design/icons-vue';
import FieldRender from "../FormRender/FieldRender.vue";
import FromRender from '../FormRender/FromRender.vue';
import FieldSetting from './FieldSetting.vue';
import FormSetting from "./FormSetting.vue";
import {defaultConfig, defaultValue, defaultPlaceholder} from '../common/defaultConfig';
import {loadOptions} from '../common/utils';

export default {
  name: 'FormDesign',
  components: {FieldRender, FromRender, FormSetting, FieldSetting, DragOutlined, DeleteOutlined},
  props: {
    showPreview: {
      type: Boolean,
      default: true
    },
  },
  data() {
    return {
      defaultConfig,
      visible: false,
      activeKey: 'formSetting',
      form: {
        settings: {
          name: '表单名称',
          labelAlign: 'right',
          layout: 'horizontal',
          labelCol: {
            span: 4
          },
          wrapperCol: {
            span: 20
          }
        },
        fields: [],
        rules: {},
        model: {},
      },
      options: {
        select: [{
          id: '1',
          name: '1'
        }, {
          id: '2',
          name: '2'
        }, {
          id: '3',
          name: '3'
        }]
      },
      field: {},
    }
  },
  methods: {
    dragstart(e, data) {
      e.dataTransfer.setData('data', JSON.stringify(data));
    },
    drop(e, index) {
      e.stopPropagation();
      let data = JSON.parse(e.dataTransfer.getData('data'));
      if (data.type === 'sort') {
        let temp = this.form.fields[data.index];
        this.form.fields.splice(data.index, 1);
        this.form.fields.splice(index, 0, temp);
      } else {
        let field = JSON.parse(JSON.stringify(defaultConfig[data.fieldType]));
        if (field.name) {
          field.name = field.name + '_' + new Date().getTime();
        }
        field.defaultValue = defaultValue[field.type];
        this.form.fields.push(field);
        this.field = field;
        this.changeClaceholder();
        this.removeSelected();
      }
    },
    ok() {
      this.$refs.render.validate().then(e => {
        console.log(e)
      }).catch(error => {
        console.log('error', error);
      });
    },
    reset() {
      this.$refs.render.reset();
    },
    click(field) {
      this.field = field;
      this.removeSelected();
      this.$refs[field.name].classList.add('selected');
    },
    removeSelected() {
      document.querySelectorAll(".design-item.selected").forEach((item) => {
        item.classList.remove('selected');
      });
    },
    changeClaceholder() {
      if (defaultPlaceholder[this.field.type]) {
        this.field.placeholder = defaultPlaceholder[this.field.type] + this.field.label;
      }
    },
    save() {
      console.log(JSON.parse(JSON.stringify(this.form)))
    },
    clear() {
      this.form.fields = [];
    },
    remove(e, index) {
      e.stopPropagation();
      let field = this.form.fields[index];
      this.form.fields.splice(index, 1);
      this.field = {};
      delete this.form.model[field.name];
      delete this.form.rules[field.name]
    },
    setDefaultValue() {
      this.form.fields.forEach((field) => {
        field.defaultValue = this.form.model[field.name];
      });
    },
    getSettings() {
      return this.form;
    },
  },
  watch: {
    'field': {
      handler(newValue, oldValue) {
        if (newValue.name) {
          this.activeKey = "fieldSetting";
        } else {
          this.activeKey = "formSetting";
        }
      },
    },
    'field.label': {
      handler(newValue, oldValue) {
        this.changeClaceholder();
      },
    }
    /*'field.datasource': {
      handler(newValue, oldValue) {
      },
    },*/
  },
  created() {
    this.form.fields.forEach((field) => {
      this.form.rules[field.name] = [];
      loadOptions(this.form.options, field);
    })
  }
}
</script>

<style scoped>
.ant-layout, .ant-layout-content, .ant-layout-sider, .ant-tabs {
  height: 100%;
  margin: 0;
}

.ant-layout-content, .ant-layout-sider {
  overflow: auto;
  background-color: white;
  outline: 1px #ebeef5 solid;
}

.ant-layout-content {
  position: relative;
}

.ant-layout-sider {
  min-width: 320px !important;
  max-width: 320px !important;
}

.ant-tabs {
  overflow: auto;
}

.design-header {
  position: absolute;
  width: 100%;
  z-index: 1000;
  height: 46px;
  line-height: 46px;
  background-color: white;
  outline: 1px #ebeef5 solid;
  top: 0;
}

.design-content {
  padding: 47px 0 0 0;
}

/*.design-setting .ant-tabs {
  overflow: hidden;
}*/

.design-body {
  margin: 0;
  overflow: auto;
}

.design-body, .design-content {
  height: 100% !important;
}

.design-setting .body {
  height: 100%;
  overflow: auto;
  padding-bottom: 40px;
}

.design-item {
  margin: 5px;
  padding: 10px;
  position: relative;
}

.design-item.selected, .design-item:hover {
  outline: 1px #1890ff dashed;
}

.design-item .delete {
  position: absolute;
  color: #1890ff;
  z-index: 3;
  right: 5px;
  bottom: 5px;
}

.design-combos {
  padding: 0;
  margin-top: 10px;
}

.design-combo {
  display: inline-block;
}

.design-combo .title {
  margin: 10px;
  outline: 1px #ebeef5 solid;
  text-align: center;
  line-height: 40px;
  width: 126px;
  height: 40px;
}
</style>
